package com.myspring.web.route.aop;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.myspring.web.route.ChannelService;
import com.myspring.web.route.RouteController;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 参考资料：
 *  spring boot 拦截器 或 Spring AOP 方式记录请求日志：https://my.oschina.net/gmd/blog/704372
 *  拦截器解析requestbody：http://stackoverflow.com/questions/10457963/spring-rest-service-retrieving-json-from-request
 */
@Aspect
@Component
public class RouteAspect implements ApplicationContextAware {
    private ApplicationContext context;

    @Pointcut("execution(public * com.myspring.web.route..*.loan*(..))")
    public void routeService() {}

    @Before("routeService()")
    public void doBefore(JoinPoint joinPoint) {
//        Class<?> clazz = joinPoint.getSignature().getDeclaringType();

        Object object = context.getBean(joinPoint.getSignature().getDeclaringType());

        if (object instanceof RouteController) {
            RouteController controller = (RouteController) object;

            //参数对象中获取bankCode
            Map<String, String> map = Maps.newHashMap();
            Object[] args = joinPoint.getArgs();
            ObjectMapper mapper = new ObjectMapper();
            try {
                String requestParam = mapper.writeValueAsString(args[0]);
                System.out.println("请求参数：" + requestParam);
                map = mapper.readValue(requestParam, HashMap.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            controller.setChannelService(this.getChannelService(map.get("bankCode")));
        }
    }

    private ChannelService getChannelService(String channelCode) {
        ChannelService channelService = null;
        Map<String, String> channelMap = (Map<String, String>) context.getBean("channelMap");

        String channelLiteral = channelMap.get(channelCode);
        Assert.notNull(channelLiteral, "未找到对应的渠道");

        try {
            Class<?> clazz = Class.forName(channelLiteral);
            channelService = (ChannelService) context.getBean(clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return channelService;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }


}
